//#include <stdio.h>
#include "AT91SAM7S64.h"

// BIT DEFINES
#define   BIT0        0x00000001
#define   BIT1        0x00000002
#define   BIT2        0x00000004
#define   BIT3        0x00000008
#define   BIT4        0x00000010
#define   BIT5        0x00000020
#define   BIT6        0x00000040
#define   BIT7        0x00000080
#define   BIT8        0x00000100
#define   BIT9        0x00000200
#define   BIT10       0x00000400
#define   BIT11       0x00000800
#define   BIT12       0x00001000
#define   BIT13       0x00002000
#define   BIT14       0x00004000
#define   BIT15       0x00008000
#define   BIT16       0x00010000
#define   BIT17       0x00020000
#define   BIT18       0x00040000
#define   BIT19       0x00080000
#define   BIT20       0x00100000
#define   BIT21       0x00200000
#define   BIT22       0x00400000
#define   BIT23       0x00800000
#define   BIT24       0x01000000
#define   BIT25       0x02000000
#define   BIT26       0x04000000
#define   BIT27       0x08000000
#define   BIT28       0x10000000
#define   BIT29       0x20000000
#define   BIT30       0x40000000
#define   BIT31       0x80000000

void InitUSART0(void);
void InitUSART1(void);

void write_char_USART0(unsigned char);
unsigned char read_char_USART0(void);
void write_char_USART1(unsigned char);
unsigned char read_char_USART1(void);

void write_str_USART0(const char* buff);
void write_str_USART1(unsigned char* buff);

unsigned char read_char_USART0_nonstop(void);
unsigned char read_char_USART1_nonstop(void);

// Pointers    
AT91PS_PIO    u_pPio    = AT91C_BASE_PIOA;   
AT91PS_PMC    u_pPMC    = AT91C_BASE_PMC;   
AT91PS_USART  u_pUSART0 = AT91C_BASE_US0;   
AT91PS_USART  u_pUSART1 = AT91C_BASE_US1;   
AT91PS_PDC    u_pPDC0   = AT91C_BASE_PDC_US0;   
AT91PS_PDC    u_pPDC1   = AT91C_BASE_PDC_US1;   
AT91PS_MC     u_pMC     = AT91C_BASE_MC;   
AT91PS_AIC    u_pAic    = AT91C_BASE_AIC;   
   
void InitUSART0(void)   
{   
   
  u_pPio->PIO_PDR = BIT5 | BIT6 | BIT21 | BIT22; //Disables the PIO from controlling the corresponding pin (enables peripheral control of the pin).    
  u_pPio->PIO_ASR = BIT5 | BIT6 | BIT21 | BIT22; //Assigns the I/O line to the Peripheral A function.    
  u_pPio->PIO_BSR = 0;                           //Assigns the I/O line to the Peripheral B function.    
   
   
  //enable the clock of USART    
  u_pPMC->PMC_PCER = 1<<AT91C_ID_US0;   
   
  //set baud rate divisor register    
  //u_pUSART0->US_BRGR = 313; //((48000000)/9600x16)  
  u_pUSART0->US_BRGR = 26; //((48000000)/115200x16)   
   
  //write the Timeguard Register    
  u_pUSART0->US_TTGR = 0;   
   
  //Set the USART mode    
  u_pUSART0->US_MR = 0x08c0;   
   
  //Enable the RX and TX PDC transfer requests    
  u_pPDC0->PDC_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN;   
   
  //Enable usart    
  u_pUSART0->US_CR = 0x50;   
   
}   
   
void InitUSART1(void)   
{   
   
  u_pPio->PIO_PDR = BIT5 | BIT6 | BIT21 | BIT22; //Disables the PIO from controlling the corresponding pin (enables peripheral control of the pin).    
  u_pPio->PIO_ASR = BIT5 | BIT6 | BIT21 | BIT22; //Assigns the I/O line to the Peripheral A function.    
  u_pPio->PIO_BSR = 0;                           //Assigns the I/O line to the Peripheral B function.    
   
   
  //enable the clock of USART    
  u_pPMC->PMC_PCER = 1<<AT91C_ID_US1;   
   
  //set baud rate divisor register    
  u_pUSART1->US_BRGR = 313; //((48000000)/9600x16)    
   
  //write the Timeguard Register    
  u_pUSART1->US_TTGR = 0;   
   
  //Set the USART mode    
  u_pUSART1->US_MR = 0x08c0;   
   
  //Enable the RX and TX PDC transfer requests    
  u_pPDC1->PDC_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN;   
   
  //Enable usart    
  u_pUSART1->US_CR = 0x50;   
   
}   
   
//write char to UART0    
void write_char_USART0(unsigned char ch)   
{   
  while (!(u_pUSART0->US_CSR&AT91C_US_TXRDY)==1);   
  u_pUSART0->US_THR = ((ch & 0x1FF));   
}   
   
//read char from UART0    
unsigned char read_char_USART0(void)   
{   
  while (!(u_pUSART0->US_CSR&AT91C_US_RXRDY)==1);   
  return((u_pUSART0->US_RHR) & 0x1FF);   
}   
   
//write char from UART0 (non stop)    
unsigned char read_char_USART0_nonstop(void)   
{   
  if((u_pUSART0->US_CSR&AT91C_US_RXRDY)==1)   
    return((u_pUSART0->US_RHR) & 0x1FF);   
  else return 0;   
}   
   
//write char to UART1    
void write_char_USART1(unsigned char ch)   
{   
  while (!(u_pUSART1->US_CSR&AT91C_US_TXRDY)==1);   
  u_pUSART1->US_THR = ((ch & 0x1FF));   
}   
   
//read char from UART1    
unsigned char read_char_USART1(void)   
{   
  while (!(u_pUSART1->US_CSR&AT91C_US_RXRDY)==1);   
  return((u_pUSART1->US_RHR) & 0x1FF);   
}   
   
//read char from UART1 (non stop)    
unsigned char read_char_USART1_nonstop(void)   
{   
  if ((u_pUSART1->US_CSR&AT91C_US_RXRDY)==1)   
    return((u_pUSART1->US_RHR) & 0x1FF);   
  else   
    return 0;   
}   
   
   
void write_str_USART0(const char* buff) {   
   
  unsigned int i = 0x0;   
   
  while(buff[i] != '\0') {   
    write_char_USART0(buff[i]);   
    i++;   
  }   
   
}   

//
//
//struct __FILE  
//{  
//int handle; 
//}; 
//
//FILE __stdout; 
//        
//int fputc(int ch, FILE *f) 
//{ 
//	write_char_USART0(ch); 
//	return ch; 
//} 

//int main(void)
//{		
//	/**** UART ****/
//	InitUSART0();
//	
//	printf("hello world\n");
//		
//	return 0;
//}
